package v2ray

import (
	"context"
	"gitee.com/Luna-CY/hui-hui/internal/application/v2ray"
	"gitee.com/Luna-CY/hui-hui/internal/interface/application"
	"gitee.com/Luna-CY/hui-hui/server/http/response"
	"github.com/gin-gonic/gin"
)

type SetOutboundVMessRequest struct {
	BaseBoundRequest
	BaseOutboundRequest

	VnextList      []SetOutboundVMessVNext   `json:"vnext_list" validate:"required" minimum:"1" binding:"required,min=1,dive"` // 服务器列表
	StreamSettings BaseStreamSettingsRequest `json:"stream_settings" validate:"optional" binding:"omitempty,dive"`             // 传输配置
}

type SetOutboundVMessVNext struct {
	Address string                   `json:"address" validate:"required" binding:"required,ip|hostname"`  // 目标地址
	Port    int                      `json:"port" validate:"required" binding:"required,min=1,max=65535"` // 目标端口
	Users   []SetOutboundVMessClient `json:"users" validate:"required" binding:"required,min=1,dive"`     // 用户配置
}

type SetOutboundVMessClient struct {
	Id    string `json:"id" validate:"required" binding:"required,min=16,max=64"` // ID
	Email string `json:"email" validate:"optional" binding:"omitempty,email"`     // 邮件地址
	Level int    `json:"level" validate:"optional" binding:"omitempty,min=0"`     // 用户级别，建设设置为0
}

func (cls *V2ray) SetOutboundVMess(c *gin.Context) (int, any, error) {
	var body = SetOutboundVMessRequest{}
	if err := c.ShouldBindJSON(&body); nil != err {
		return response.InvalidRequest, nil, err
	}

	var ctx = context.Background()

	var vnextList []*application.V2rayVMessVnext
	for _, vnext := range body.VnextList {
		var users = make([]*application.V2rayVMessClient, 0)
		for _, client := range vnext.Users {
			users = append(users, &application.V2rayVMessClient{Id: client.Id, Email: client.Email, Level: client.Level, Security: "auto"})
		}

		var item = &application.V2rayVMessVnext{Address: vnext.Address, Port: vnext.Port, Users: users}
		vnextList = append(vnextList, item)
	}

	var protocol, err = v2ray.NewVMessOutbound(body.Id, body.Tag, body.OutboundSendThrough, vnextList, body.StreamSettings.build())
	if nil != err {
		return response.InvalidRequest, nil, err
	}

	if err := cls.v2ray.SetOutbound(ctx, protocol.Id, protocol); nil != err {
		return response.Unknown, nil, err
	}

	// 应用配置
	if err := cls.v2ray.ApplyConfig(ctx); nil != err {
		return response.Unknown, nil, err
	}

	return response.Ok, nil, nil
}
